package org.example.SFTP;

import com.jcraft.jsch.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

public class SftpClient {
    private ChannelSftp sftp;
    private Session session;
    private String host; // SFTP服务器地址
    private int port; // SFTP服务器端口
    private String username; // 用户名
    private String password; // 密码

    /**
     * 构造函数
     * @param host 主机地址
     * @param port 端口号
     * @param username 用户名
     * @param password 密码
     */
    public SftpClient(String host, int port, String username, String password) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    /**
     * 连接SFTP服务器
     */
    public void connect() throws JSchException {
        JSch jsch = new JSch();
        session = jsch.getSession(username, host, port);
        session.setPassword(password);
        
        // 设置连接属性
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no"); // 不检查主机密钥
        session.setConfig(config);
        
        // 连接超时时间30秒
        session.setTimeout(30000);
        session.connect();
        
        // 打开SFTP通道
        Channel channel = session.openChannel("sftp");
        channel.connect();
        sftp = (ChannelSftp) channel;
        System.out.println("SFTP服务器连接成功");
    }

    /**
     * 上传文件
     * @param localFilePath 本地文件路径
     * @param remoteDir 远程目录
     */
    public void uploadFile(String localFilePath, String remoteDir) throws Exception {
        File localFile = new File(localFilePath);
        if (!localFile.exists()) {
            throw new Exception("本地文件不存在: " + localFilePath);
        }
        
        // 切换到远程目录，不存在则创建
        try {
            sftp.cd(remoteDir);
        } catch (SftpException e) {
            sftp.mkdir(remoteDir);
            sftp.cd(remoteDir);
        }
        
        // 上传文件
        try (FileInputStream fis = new FileInputStream(localFile)) {
            sftp.put(fis, localFile.getName());
            System.out.println("文件上传成功: " + localFile.getName());
        }
    }

    /**
     * 下载文件
     * @param remoteFilePath 远程文件路径
     * @param localDir 本地目录
     */
    public void downloadFile(String remoteFilePath, String localDir) throws Exception {
        File localDirFile = new File(localDir);
        if (!localDirFile.exists()) {
            localDirFile.mkdirs();
        }
        
        String fileName = new File(remoteFilePath).getName();
        String localFilePath = localDir + File.separator + fileName;
        
        // 下载文件
        try (FileOutputStream fos = new FileOutputStream(localFilePath)) {
            sftp.get(remoteFilePath, fos);
            System.out.println("文件下载成功: " + localFilePath);
        }
    }

    /**
     * 关闭连接
     */
    public void disconnect() {
        if (sftp != null && sftp.isConnected()) {
            sftp.disconnect();
        }
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
        System.out.println("SFTP连接已关闭");
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        // 替换为你的SFTP服务端配置
        String host = "localhost";
        int port = 22;
        String username = "your_username"; // 你设置的用户名
        String password = "your_password"; // 你设置的密码
        
        SftpClient client = new SftpClient(host, port, username, password);
        
        try {
            // 连接服务器
            client.connect();
            
            // 上传测试文件
            String localUploadFile = "C:/test/upload.txt"; // 本地要上传的文件
            client.uploadFile(localUploadFile, "/upload");
            
            // 下载测试文件
            String remoteDownloadFile = "/upload/upload.txt"; // 远程要下载的文件
            String localDownloadDir = "C:/test/download"; // 本地保存目录
            client.downloadFile(remoteDownloadFile, localDownloadDir);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接
            client.disconnect();
        }
    }
}
    